package com.itheima.server.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.common.core.domain.AjaxResult;
import com.itheima.common.core.domain.entity.SysUser;
import com.itheima.common.utils.SecurityUtils;
import com.itheima.common.utils.StringUtils;
import com.itheima.server.Enum.ClueStatus;
import com.itheima.server.domain.Business;
import com.itheima.server.domain.CluBusSave;
import com.itheima.server.domain.Clue;
import com.itheima.server.domain.ClueFollow;
import com.itheima.server.dto.*;
import com.itheima.server.mapper.BusinessMapper;
import com.itheima.server.mapper.ClueFollowMapper;
import com.itheima.server.mapper.ClueMapper;
import com.itheima.server.service.ClueService;
import com.itheima.server.service.RuleService;
import com.itheima.system.mapper.SysUserMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Slf4j
public class CluServiceImpl extends ServiceImpl<ClueMapper, Clue> implements ClueService {
    private final ClueMapper clueMapper;
    private final SysUserMapper sysUserMapper;
    private final ClueFollowMapper clueFollowMapper;
    private static final String STATUS_DATA = "1";
    private static final String TRANSFER_DATA = null;
    private final BusinessMapper businessMapper;
    private  final RuleService ruleService;
    private static final Integer ZERO_TYPE=0;
    @Override
    public List<Clue> getList(ClueQueryPage queryPage) {
        LocalDateTime begin = null;
        LocalDateTime end = null;
        if(queryPage.getParams()!=null){
            String beginCreateTime  = queryPage.getParams().get("beginCreateTime");
            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            if(beginCreateTime!=""){
                begin = LocalDateTime.parse(beginCreateTime, dateTimeFormatter);
            }

            String endCreateTime = queryPage.getParams().get("endCreateTime");

            if (endCreateTime!=""){
                end = LocalDateTime.parse(endCreateTime, dateTimeFormatter);
            }}
        LambdaQueryWrapper<Clue> clueLambdaQueryWrapper = new LambdaQueryWrapper<>();
        clueLambdaQueryWrapper.notIn(Clue::getStatus,"3","4","5")
                .eq(queryPage.getId()!=null,Clue::getId,queryPage.getId())
                .eq(queryPage.getPhone()!=null,Clue::getPhone,queryPage.getPhone())
                .eq(queryPage.getChannel()!=null,Clue::getChannel,queryPage.getChannel())
                .eq(queryPage.getStatus()!=null,Clue::getStatus,queryPage.getStatus())
                .between(begin!=null&&end!=null,Clue::getCreateTime,begin,end);

        Page<Clue> page = new Page<>(queryPage.getPageNum(), queryPage.getPageSize());
      super.page(page,clueLambdaQueryWrapper);
        return page.getRecords();
    }

    @Override
    public void add(Clue clue) {
        log.info("添加线索：{}",clue);
        Date date = new Date();

        clue.setCreateTime(date);
        String username = SecurityUtils.getUsername();
        clue.setCreateBy( username);
        clue.setOwner( username);



        clueMapper.insert(clue);

    }

    /**
     *
     * 根据ID查询线索
     * @param id
     * @return
     */

    @Override
    public Clue getCluById(Integer id) {
        Clue clue = clueMapper.selectById(id);

        return clue;
    }

    @Override
    public  List<ClueFollow> getSubjectList(Integer clueId) {
        log.info("查询线索跟进：{}",clueId);

        LambdaQueryWrapper<ClueFollow> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ClueFollow::getClueId,2);
        List<ClueFollow> clueFollows = clueFollowMapper.selectList(queryWrapper);

        log.info("查询结果：{}",clueFollows);

        return clueFollows;
    }

    @Override
    @Transactional
    public void addRecord(ClueFollow clueFollow) {
        log.info("添加跟进：{}",clueFollow);
        log.info("线索ID：{}",clueFollow.getNextTime());
        Clue clue = clueMapper.selectOne(Wrappers.<Clue>lambdaQuery().eq(Clue::getId, clueFollow.getClueId()));
        String status = clue.getStatus();

            clue.setStatus("2");
            clue.setNextTime(clueFollow.getNextTime());
        clue.setName(clueFollow.getName());
        if (clueFollow.getSex()!=null){
            clue.setSex(clueFollow.getSex());
        }
        if (clueFollow.getAge()!=null){
            clue.setAge(clueFollow.getAge());
        }
        if (clueFollow.getWeixin()!=null){
            clue.setWeixin(clueFollow.getWeixin());
        }
        if (clueFollow.getQq()!=null){
            clue.setQq(clue.getQq());
        }
        clue.setUpdateTime(new Date());
        clue.setUpdateBy(SecurityUtils.getUsername());
            clueMapper.updateById(clue);




        clueFollowMapper.insert(clueFollow);

    }

    @Override
    public void falseClue(Integer id, ClueFalseReasonDto clueFalseReasonDto) {
        Clue clue = clueMapper.selectById(id);
        Integer falseCount = clue.getFalseCount()==null?0:clue.getFalseCount();
        if(falseCount==2){
            clue.setStatus("4");
            super.updateById( clue);
           return;

        }
        falseCount++;
        clue.setFalseCount(falseCount);
        clue.setTransfer("1");
        clue.setStatus(ClueStatus.INVALID.status.toString());
        clue.setFalsereason(clueFalseReasonDto.getFalseReason());
        clue.setRemark(clueFalseReasonDto.getRemark());
        LambdaQueryWrapper<Clue> clueLambdaQueryWrapper = new LambdaQueryWrapper<>();
        clueLambdaQueryWrapper.eq(Clue::getId,id);
        clueMapper.update(clue,clueLambdaQueryWrapper);



    }

    @Override
    public List<Clue> getPoolList(CluePoolPageDto cluePoolPageDto) {
        Page<Clue> page = new Page<>(cluePoolPageDto.getPageNum(), cluePoolPageDto.getPageSize());
        LocalDateTime begin = null;
        LocalDateTime end = null;
        if(cluePoolPageDto.getParams()!=null){
        String beginCreateTime  = cluePoolPageDto.getParams().get("beginCreateTime");
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
       if(beginCreateTime!=""){
            begin = LocalDateTime.parse(beginCreateTime, dateTimeFormatter);
       }

        String endCreateTime = cluePoolPageDto.getParams().get("endCreateTime");

       if (endCreateTime!=""){
           end = LocalDateTime.parse(endCreateTime, dateTimeFormatter);
       }}
Integer id = cluePoolPageDto.getId();
        String phone = cluePoolPageDto.getPhone();
        String channel = cluePoolPageDto.getChannel();
        String status ="3";
        String transfer ="1";
        LambdaQueryWrapper<Clue> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.between(begin!=null&&end!=null,Clue::getCreateTime,begin,end)
                .eq(StringUtils.hasText( phone),Clue::getPhone,phone)
                .eq(StringUtils.hasText( channel),Clue::getChannel,channel)
                .eq(Clue::getStatus,status)
                .eq(Clue::getTransfer,transfer)
                .eq(id!=null,Clue::getId,id);
clueMapper.selectPage(page,queryWrapper);


//        List<Clue> poolList = clueMapper.getPoolList(begin, end, id, phone, channel, status, transfer);



        return page.getRecords();
    }

    @Override
    public void gainClue(List<Integer> ids) {
        List<Clue> collect = ids.stream().map(id -> {
            Clue clue = new Clue();
            clue.setId(id);
            clue.setStatus(STATUS_DATA);
            clue.setTransfer(TRANSFER_DATA);
            return clue;
        }).collect(Collectors.toList());
        super.updateBatchById( collect);
    }

    @Override
    public AjaxResult assigment(CluAssignmentDto cluAssignmentDto) {
       log.info("线索分配：{}",cluAssignmentDto);
       // 获取用户ID
        Long userId = cluAssignmentDto.getUserId();
        SysUser user = sysUserMapper.selectUserById(userId);
        String name = user.getUserName();
        //根据用户名查询保有量
        LambdaQueryWrapper<Clue> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Clue::getOwner,name)
                .in(Clue::getStatus,STATUS_DATA, ClueStatus.ASSIGNED);
        int count = super.count(queryWrapper);
        //判断是否超过最大保有量
        CluBusSave disposition = ruleService.getDisposition(ZERO_TYPE);
        Integer maxNunmber = disposition.getMaxNunmber();
        //TODO
        List<Integer> ids = cluAssignmentDto.getIds();

        if(count+ids.size()>maxNunmber){
           return AjaxResult.error("分配失败,该用户线索数量已满");
        }

        List<Clue> collect = ids.stream().map(id -> {
            Clue clue = new Clue();
            clue.setId(id);
            clue.setOwner(name);

            clue.setOwnerTime(new Date());
            clue.setAssignBy(SecurityUtils.getUsername());
            clue.setAssignTime(new Date());
            clue.setUpdateBy(SecurityUtils.getUsername());
            clue.setUpdateTime(new Date());
            return clue;

        }).collect(Collectors.toList());
        super.updateBatchById( collect);
        return AjaxResult.success();
    }

    @Override
    public  void  saveList(List<Clue> clueList, HashMap<String, Integer> map) {
        //遍历列表计数
        try {
            for (Clue clue : clueList) {
                boolean saved = save(clue);
                if (saved){
                    //若无这个键则创建，若有则加1
                    map.put("successNum",map.get("successNum")==null?1:map.get("successNum")+1);
                }else {
                    map.put("failureNum",map.get("failNum")==null?1:map.get("failureNum")+1);
                }
            }
        }catch (Exception e){
            log.error("导入出错 {}" ,e);
        }
    }

    @Override
    @Transactional
    public AjaxResult changeBusiness(Clue clue, Integer id) {
        Clue clue1 = super.getById(id);

        LambdaQueryWrapper<ClueFollow> eq = Wrappers.<ClueFollow>lambdaQuery()
                .eq(ClueFollow::getClueId, id);
        List<ClueFollow> clueFollows = clueFollowMapper.selectList(eq);

        if (clueFollows!=null &&  clueFollows.size()>0 ){
            try {
                Business business = new Business();
                ClueFollow clueFollow = Collections.max(clueFollows, Comparator.comparing(ClueFollow::getCreateTime));
                BeanUtils.copyProperties(clue1,business);
                business.setId(null);
                business.setSubject(clueFollow.getSubject());
                business.setStatus(1);
                business.setFalseCount(0);
                businessMapper.insert(business);
                clue1.setStatus("5");
               clueMapper.updateById(clue1);
//                clueMapper.deleteById(id);
//                clueFollowMapper.delete(eq);
            } catch (Exception e) {
               log.error("转换出错 {}",e);
               return AjaxResult.error("转换失败");

            }

        }else {
            //ToDo 添加业务
            try {
                Business business1 = new Business();
                BeanUtils.copyProperties(clue1,business1);
//            String name = business1.getName();

                business1.setId(null);
                business1.setStatus(1);
                business1.setFalseCount(0);
                business1.setSubject("1");
                businessMapper.insert(business1);
//                clueMapper.deleteById(id);
//                clueFollowMapper.delete(eq);

                clue1.setStatus("5");
                clueMapper.updateById(clue1);
            } catch (BeansException e) {
                log.error("转换出错 {}",e);
                return AjaxResult.error("转换失败");
            }

        }


return AjaxResult.success("转换成功");

    }
}
